<!--
 * @Author: zhangpeng
 * @Date: 2024-03-05 08:44:50
 * @FilePath: \dcy-web\packages\materials\components\Project\Rules\components\AddReachRule.vue
 * @LastEditTime: 2024-09-02 17:17:31
 * @Description: 设置评价指标
-->

<script setup lang="ts">
import { Message } from '@arco-design/web-vue'
import CryptoJS from 'crypto-js'
import { addReachRuleReq, editReachRuleReq, getRuleIloListReq, resolvingEvaluateContentReq } from '../../../../services/project/achieve'
import type { AddReachRuleParams, ProjectPhaseIloListResp, ProjectReachRuleListResp } from '../../../../types/project/achieve.ts'

const props = defineProps<{
  show: boolean
  projectId?: string
  phaseId?: string
  editRuleItem?: ProjectReachRuleListResp
  iloDisabled?: boolean //  ilo预期结果 / 本阶段任务禁用输入
}>()
const emits = defineEmits(['openModal'])
const formRef = ref()
// 解析内容
const resolvingContent = ref('')
// 解析 输入框 获取焦点
const resolvingFocus = ref(false)
// 解析输入框是否展开
const resolvingOpen = ref(true)

const iloList = ref<ProjectPhaseIloListResp[]>([])

const formData = ref<AddReachRuleParams>({
  projectIloId: undefined,
  phaseId: undefined,
  projectId: undefined,
  ruleListDTOList: [
    {
      evaluationCriterion: '',
      fullScore: undefined,
      ruleRefineDTOList: [],
    },
  ],
  taskName: '',
})

// 总分值是否为100
const fullScoreThan = computed(() => {
  let score = 0
  formData.value.ruleListDTOList.forEach((item) => {
    score += (item.fullScore ?? 0)
  })
  return score
})

// 通过评价标准title进行去重
function removeDuplicatesByEvaluationCriterion<T extends { evaluationCriterion: string }>(items: T[]): T[] {
  const seenIds = new Set<string>()
  return items.filter((item) => {
    if (!seenIds.has(item.evaluationCriterion)) {
      seenIds.add(item.evaluationCriterion)
      return true
    }
    return false
  })
}

// 解析输入的评价标准
const { run: resolvingEvaluateContent, loading: resolvingLoading } = useRequest(resolvingEvaluateContentReq, {
  manual: true,
  onSuccess: (data) => {
    if (data) {
      const tempList = data.ruleListDTOList.map((item: any) => {
        return {
          ...item,
          ruleRefineDTOList: (item?.ruleRefineDTOList && item?.ruleRefineDTOList.length > 0) ? item?.ruleRefineDTOList : [{ name: '', minScore: undefined, maxScore: undefined }],
          hash: computeWebHash(`${createRandomNumbers()}-${getLocalEnvTimestamp()}`),
        }
      })
      const uniqueEvaluate: any = []
      removeDuplicatesByEvaluationCriterion([...tempList, ...formData.value.ruleListDTOList]).forEach((item) => {
        if (item.evaluationCriterion !== '')
          uniqueEvaluate.push(item)
      })
      formData.value.ruleListDTOList = uniqueEvaluate
      formRef.value.validate()
    }
  },
  onError: () => {
  },
})

// 查询可选的ilo列表
const { run: getRuleIloList } = useRequest(getRuleIloListReq, {
  manual: true,
  onSuccess: (data) => {
    if (data)
      iloList.value = data
  },
  onError: () => {
  },
})

// 创建接口
const { run: addReachRuleRequest, loading: addLoading } = useRequest(addReachRuleReq, {
  manual: true,
  onSuccess: (data) => {
    if (data?.isSuccess)
      emits('openModal', false, true)
  },
  onError: () => {
  },
})

// 编辑接口
const { run: editReachRuleRequest, loading: updateLoading } = useRequest(editReachRuleReq, {
  manual: true,
  onSuccess: (data) => {
    if (data?.isSuccess)
      emits('openModal', false, true)
  },
  onError: () => {
  },
})

// 解析输入框 失焦 开启解析
const resolvingOnBlur = () => {
  if (resolvingContent.value !== '') { // 解析
    if (resolvingContent.value.trim().length > 0) {
      const params = {
        projectIloId: formData.value.projectIloId,
        phaseId: props.phaseId,
        ruleData: resolvingContent.value,
      }
      resolvingEvaluateContent(params)
    }
  }
}

// 创建
// eslint-disable-next-line unused-imports/no-unused-vars
async function createReachRule({ values, errors }: { values: any, errors: any }) {
  formRef.value.validate((errors: any) => {
    if (!errors) {
      if (props.editRuleItem) { //  编辑
        editReachRuleRequest(formData.value)
      }
      else { //  创建
        formData.value.phaseId = props.phaseId
        formData.value.projectId = props.projectId
        addReachRuleRequest(formData.value)
      }
    }
  })
}

// 生成hash值，唯一性区分
function computeWebHash(input: string) {
  return CryptoJS.SHA256(input).toString()
}

function getLocalEnvTimestamp() {
  // 创建一个Date对象，它会自动设置为当前日期和时间
  const now = new Date()
  // 使用getTime()方法获取时间戳（毫秒）
  const timestamp = now.getTime()
  return timestamp
}

function createRandomNumbers() {
  return Math.random()
}

// 校验总分
function checkRules() {
  formRef.value.validate()
}

// 添加阶段评价标准
function addRule() {
  formData.value.ruleListDTOList.push({
    evaluationCriterion: '',
    fullScore: undefined,
    ruleRefineDTOList: [{ name: '', minScore: undefined, maxScore: undefined, hash: computeWebHash(`${createRandomNumbers()}-${getLocalEnvTimestamp()}`) }],
    hash: computeWebHash(`${createRandomNumbers()}-${getLocalEnvTimestamp()}`),
  })
}
// 删除阶段评价标准
function delRule(index: number) {
  formData.value.ruleListDTOList.splice(index, 1)
  // 进行校验，将之前显示的红色警告消除
  formRef.value.validate()
}

// 新增 标准细化
const refineStandardRule = (index: number) => {
  if (formData.value?.ruleListDTOList && formData.value.ruleListDTOList[index].ruleRefineDTOList.length === 10) {
    // 拦截
    Message.error('最多新增10个区间')
    return false
  }
  if (formData.value?.ruleListDTOList && formData.value?.ruleListDTOList.length > index)
    formData.value.ruleListDTOList[index].ruleRefineDTOList.push({ name: '', minScore: undefined, maxScore: undefined, hash: computeWebHash(`${createRandomNumbers()}-${getLocalEnvTimestamp()}`) })
}

// 复制细化规则
const copyRefineRule = (x: number, y: number) => {
  if (formData.value?.ruleListDTOList && formData.value.ruleListDTOList[x].ruleRefineDTOList.length === 10) {
    // 拦截
    Message.error('最多新增10个区间')
    return false
  }
  if (formData.value?.ruleListDTOList && formData.value?.ruleListDTOList.length > y) {
    // 需要复制的数据
    const temp = formData.value.ruleListDTOList[x].ruleRefineDTOList[y]
    formData.value.ruleListDTOList[x].ruleRefineDTOList.push({ name: temp.name, hash: computeWebHash(`${createRandomNumbers()}-${getLocalEnvTimestamp()}`) })
  }
}

// 删除细化规则
const delRefineRule = (x: number, y: number) => {
  if (formData.value?.ruleListDTOList && formData.value?.ruleListDTOList.length > y)
    formData.value.ruleListDTOList[x].ruleRefineDTOList.splice(y, 1)
}

function onHandleCancel() {
  emits('openModal', false)
}

// 监听 解析输入框 是否获取焦点
watch(
  () => resolvingFocus.value,
  () => {
    document.documentElement.style.setProperty('--textarea-word-limit-right', resolvingFocus.value ? '10px' : '60px')
  },
  {
    immediate: true,
  },
)

onMounted(() => {
  // 编辑回填
  if (props.editRuleItem) {
    const editRuleItem = JSON.parse(JSON.stringify(props.editRuleItem))
    getRuleIloList({ phaseId: props?.editRuleItem?.phaseId })

    // 整理数据，添加hash值，标记唯一性
    editRuleItem?.ruleListDTOList.forEach((item) => {
      item.hash = computeWebHash(`${createRandomNumbers()}-${getLocalEnvTimestamp()}`)
      item?.ruleRefineDTOList.forEach((i) => {
        i.hash = computeWebHash(`${createRandomNumbers()}-${getLocalEnvTimestamp()}`)
      })
    })
    formData.value = {
      projectIloId: editRuleItem.projectIloId,
      oldProjectIloId: editRuleItem.projectIloId,
      phaseId: editRuleItem.phaseId,
      projectId: editRuleItem.projectId,
      ruleListDTOList: editRuleItem?.ruleListDTOList && editRuleItem?.ruleListDTOList?.length
        ? editRuleItem?.ruleListDTOList
        : [{ evaluationCriterion: '', fullScore: undefined, ruleRefineDTOList: [{ name: '', minScore: undefined, maxScore: undefined }], hash: computeWebHash(`${createRandomNumbers()}-${getLocalEnvTimestamp()}`) }],
      taskName: editRuleItem.taskName,
    }
  }
  else {
    getRuleIloList({ phaseId: props.phaseId! })
  }
})
</script>

<template>
  <div class="drawer-style">
    <a-drawer v-if="props.show" :width="990" :visible="props.show" unmount-on-close :ok-text="`${props.editRuleItem ? '保存' : '确定添加'}`" @cancel="onHandleCancel" @ok="createReachRule">
      <template #title>
        <div class="drawer-style-header">
          设置评价标准
        </div>
      </template>
      <a-spin :loading="addLoading || updateLoading" class="drawer-style-content">
        <a-form ref="formRef" size="medium" :model="formData" auto-label-width :style="{ width: '100%' }" @submit="createReachRule">
          <div class="section-title">
            <a-form-item label="预期学习结果(ILO)名称" :rules="[{ required: true, message: '' }]" />
          </div>
          <div class="section-content">
            <a-form-item field="projectIloId" label="" :rules="[{ required: !iloDisabled, message: '请选择' }]">
              <a-select v-model="formData.projectIloId" placeholder="请选择" allow-clear :disabled="iloDisabled">
                <a-option v-for="item in iloList" :key="item.projectIloId" :value="item.projectIloId" :disabled="!item.related">
                  {{ item.projectIloName }}
                </a-option>
              </a-select>
            </a-form-item>
          </div>
          <div class="section-content mt-[20px]">
            <a-form-item
              v-if="resolvingOpen" field="resolveText" label="" class="relative"
            >
              <a-textarea
                v-model="resolvingContent" :style="{ backgroundColor: '#F3F3FF', border: '1px solid #CDCDFF' }" :auto-size="{ minRows: 4 }"
                :max-length="500" :allow-clear="true" show-word-limit
                :placeholder="`评价标准粘贴处，粘贴指定格式的数据，系统将自动解析数据，${'举例:'}\n${'1.评价标准1(30)'}\n${'2.评价标准2(50)'}\n${'3.评价标准3(20)'}`" class="custom-textarea"
                @blur="() => { resolvingFocus = false, resolvingOnBlur() }" @focus="() => resolvingFocus = true"
              />
              <div class="arco-textarea-word-limit mb-[-6px] mr-[-10px]">
                <a-button type="text" @click="resolvingOpen = false">
                  <i class="iconfont icon-a-Property1shangProperty2jiantou text-[12px] color-[#6B6AFF]" />
                  收起
                </a-button>
              </div>
              <div v-if="resolvingLoading" class="resolving-mask">
                <span class="text-[14px] color-white">识别中...</span>
              </div>
            </a-form-item>
            <a-form-item
              v-else field="resolveText" label="" class="relative"
            >
              <div
                class="resolvingRule"
                style="border: 1px solid #CDCDFF;white-space: nowrap;text-overflow: ellipsis;"
                @click="resolvingOpen = true"
              >
                <span v-if="resolvingContent === ''" class="color-[#86909C]">评价标准粘贴处，点击展开查看规则</span>
                <span v-else>{{ resolvingContent }}</span>
              </div>
              <div class="arco-textarea-word-limit mb-[-6px] mr-[-10px]">
                <a-button type="text" @click="resolvingOpen = true">
                  <i class="iconfont icon-a-Property1xiaProperty2jiantou text-[12px] color-[#6B6AFF]" />
                  展开
                </a-button>
              </div>
            </a-form-item>
          </div>
          <div class="section-title mt-[20px]">
            <a-form-item label="本阶段评价标准" :rules="[{ required: true, message: '' }]" />
          </div>
          <div v-for="(item, index) in formData.ruleListDTOList" :key="item.hash" class="flex flex-col">
            <div class="section-content flex flex-col" :style="{ marginTop: index !== 0 ? '32px' : '0px' }">
              <div class="flex flex-row">
                <div class="phaseEvaluate-desc">
                  <a-form-item
                    :field="`ruleListDTOList[${index}][evaluationCriterion]`" label=""
                    :rules="[
                      { required: true, message: '请填写本阶段评价标准描述' },
                    ]"
                    :validate-trigger="['change', 'input', 'blur']"
                    class="no-require"
                  >
                    <a-textarea v-model="formData.ruleListDTOList[index].evaluationCriterion" :style="{ width: '631px' }" placeholder="请填写本阶段评价标准描述" :max-length="50" show-word-limit :auto-size="{ minRows: 1 }" class="custom-standard-textarea mr-4 flex-none" />
                  </a-form-item>
                </div>
                <div class="phaseEvaluate">
                  <a-form-item
                    :field="`ruleListDTOList[${index}][fullScore]`"
                    :rules="[
                      {
                        required: true,
                        message: '请填写分值',
                      }, {
                        validator: (value, cb) => {
                          if (fullScoreThan !== 100) {
                            cb(`分值之和需等于100，当前为${fullScoreThan}`)
                          }
                          else {
                            cb('')
                          }
                        },
                      },
                    ]"
                    :validate-trigger="['change', 'blur']"
                  >
                    <a-input-number v-model="formData.ruleListDTOList[index].fullScore" :style="{ width: '120px' }" placeholder="请填写分值" :min="1" :max="100" :precision="0" :step="1" @blur="checkRules" />
                  </a-form-item>
                </div>
                <div class="phaseEvaluate">
                  <a-form-item class="mr-[16px] w-[110px]">
                    <a-button class="w-[110px]" @click="refineStandardRule(index)">
                      <template #icon>
                        <icon-plus />
                      </template>
                      标准细化
                    </a-button>
                  </a-form-item>
                </div>
                <icon-close v-if="formData.ruleListDTOList?.length > 1" class="ml-2 flex-none cursor-pointer leading-[32px] h-[32px]!" @click="delRule(index)" />
                <span v-else class="ml-2 w-[14px] flex-none" />
              </div>
              <div v-for="(subItem, yIndex) in formData.ruleListDTOList[index].ruleRefineDTOList" :key="subItem.hash" class="subPhase">
                <div class="refineRow">
                  <a-form-item
                    :field="`ruleListDTOList[${index}][ruleRefineDTOList][${yIndex}][name]`" :label="`区间${yIndex + 1}`"
                    :rules="[
                      { required: true, message: '请输入' },
                    ]"
                    :validate-trigger="['change', 'input', 'blur']"
                    class="no-require"
                  >
                    <a-textarea v-model="formData.ruleListDTOList[index].ruleRefineDTOList[yIndex].name" :style="{ width: '529px' }" placeholder="请填写评价标准细化描述" :max-length="50" show-word-limit :auto-size="{ minRows: 1 }" class="custom-standard-textarea mr-4 flex-none" />
                  </a-form-item>
                </div>
                <div class="phaseEvaluate">
                  <a-form-item
                    :field="`ruleListDTOList[${index}][ruleRefineDTOList][${yIndex}][minScore]`"
                    :rules="[
                      { required: true, message: '请输入' }, {
                        validator: (value, cb) => {
                          if (formData.ruleListDTOList[index].fullScore === undefined) {
                            cb('')
                          }
                          else if (value > formData.ruleListDTOList[index].fullScore) {
                            cb(`无法大于${formData.ruleListDTOList[index].fullScore}`)
                          }
                          else if (yIndex > 0 && value <= formData.ruleListDTOList[index].ruleRefineDTOList[yIndex - 1].maxScore) {
                            cb(`需大于${formData.ruleListDTOList[index].ruleRefineDTOList[yIndex - 1].maxScore}`)
                          }
                          else if (value > formData.ruleListDTOList[index].ruleRefineDTOList[yIndex].maxScore) {
                            cb(`需小于等于${formData.ruleListDTOList[index].ruleRefineDTOList[yIndex].maxScore}`)
                          }
                          else {
                            cb('')
                          }
                        },
                      },
                    ]"
                    :validate-trigger="['change', 'blur']"
                  >
                    <a-input-number v-model="formData.ruleListDTOList[index].ruleRefineDTOList[yIndex].minScore" :style="{ width: '120px' }" placeholder="请填写分值" :min="0" :max="100" :precision="0" :step="1" @blur="checkRules" />
                  </a-form-item>
                </div>
                <div class="h-32px w-24px text-center lh-32px">
                  -
                </div>
                <div class="phaseEvaluate" style="margin-left: 0px;">
                  <a-form-item
                    :field="`ruleListDTOList[${index}][ruleRefineDTOList][${yIndex}][maxScore]`"
                    :rules="[
                      { required: true, message: '请输入' }, {
                        validator: (value, cb) => {
                          if (formData.ruleListDTOList[index].fullScore === undefined) {
                            cb('')
                          }
                          else if (value > formData.ruleListDTOList[index].fullScore) {
                            cb(`无法大于${formData.ruleListDTOList[index].fullScore}`)
                          }
                          else if (yIndex < formData.ruleListDTOList[index].ruleRefineDTOList.length - 1 && value >= formData.ruleListDTOList[index].ruleRefineDTOList[yIndex + 1].minScore) {
                            cb(`需小于${formData.ruleListDTOList[index].ruleRefineDTOList[yIndex + 1].minScore}`)
                          }
                          else if (value < formData.ruleListDTOList[index].ruleRefineDTOList[yIndex].minScore) {
                            cb(`需大于等于${formData.ruleListDTOList[index].ruleRefineDTOList[yIndex].minScore}`)
                          }
                          else {
                            cb('')
                          }
                        },
                      },
                    ]"
                    :validate-trigger="['change', 'blur']"
                  >
                    <a-input-number v-model="formData.ruleListDTOList[index].ruleRefineDTOList[yIndex].maxScore" :style="{ width: '120px' }" placeholder="请填写分值" :min="0" :max="100" :precision="0" :step="1" @blur="checkRules" />
                  </a-form-item>
                </div>
                <div class="copy-item">
                  <icon-copy @click="copyRefineRule(index, yIndex)" />
                </div>
                <div class="copy-item">
                  <icon-close @click="delRefineRule(index, yIndex)" />
                </div>
              </div>
            </div>
          </div>
          <div class="section-content-btn">
            <a-form-item>
              <a-button type="primary" @click="addRule">
                <template #icon>
                  <icon-plus />
                </template>
                <template #default>
                  新增评价标准
                </template>
              </a-button>
            </a-form-item>
          </div>
        </a-form>
      </a-spin>
    </a-drawer>
  </div>
</template>

<style lang="less" scoped>
.drawer-style {
  --at-apply: relative;
  &-header {
    --at-apply: text-14px font-bold color-#1D2129;
  }
  .resolvingRule {
    --at-apply: h-[32px] w-full overflow-hidden bg-[#F3F3FF] pl-[12px] pr-[70px] lh-[32px];
  }
  &-content {
    width: calc(100% - 32px);
    margin: 3px 16px;
    // 分区头
    .section-title {
      --at-apply: h-[30px] w-full;
      :deep(.arco-form-item-label-col) {
        --at-apply: lh-[22px] h-[22px] text-14px font-normal color-#4E5969;
        flex: none !important;
      }
    }
    // 分区内容
    .section-content {
      --at-apply: h-auto w-full;
      // 去除form内容的头
      :deep(.arco-form-item-label-col) {
        flex: 0 !important;
        padding-right: 0px;
      }
      :deep(.arco-form-item) {
        margin-bottom: 0px;
      }
      .subPhase {
        --at-apply: mt-[20px] flex flex-row;
        // 细化规则
        .refineRow {
          :deep(.arco-form-item-label-col) {
            flex: 0 0 53px !important;
            padding-right: 0px;
            justify-content: flex-start;
          }
          // 本阶段评价标准细化
          :deep(.arco-textarea-wrapper) {
            --at-apply: bg-white;
            border: 1px solid #E5E6EB;
          }
        }
      }
    }
    .section-content-btn {
      --at-apply: h-auto w-full mt-20px justify-center;
      // 去除form内容的头
      :deep(.arco-form-item-label-col) {
        flex: 0 !important;
        padding-right: 0px;
      }
      :deep(.arco-form-item) {
        margin-bottom: 0px;
      }
      :deep(.arco-form-item-content-flex) {
        justify-content: center;
      }
    }
  }
}

:root {
  --textarea-word-limit-right: 60px; /* 默认值 */
}

// 复制按钮
.copy-item {
  --at-apply: h-32px w-32px;
  :deep(.arco-icon) {
    --at-apply: w-16px h-16px mt-8px ml-16px cursor-pointer;
  }
}

// 本阶段评价标准
.phaseEvaluate-desc {
  --at-apply: w-631px;
  // 本阶段评价标准描述
  :deep(.arco-textarea-wrapper) {
    --at-apply: bg-white;
    border: 1px solid #E5E6EB;
  }
}
.phaseEvaluate {
  --at-apply: ml-16px w-120px;
  // 告警提示文字
  :deep(.arco-form-item-message) {
    white-space: nowrap;
  }
  :deep(.arco-form-item-label-required-symbol){
    display: none;
  }
  :deep(.arco-form-item-label-col){
    display: none
  }
  // 分值输入框
  :deep(.arco-input-wrapper) {
    background-color: white;
    border: 1px solid #E5E6EB;
  }
  // 标准细化 按钮
  :deep(.arco-btn-secondary, .arco-btn-secondary[type='button'], .arco-btn-secondary[type='submit']) {
    --at-apply: bg-white color-#1D2129 text-14px;
    border: 1px solid #E5E6EB;
  }
}

// 解析遮罩层
.resolving-mask {
  --at-apply: absolute left-[158.99px] top-[0px] right-[0px] h-full flex justify-center;
  background-color: rgba(0, 0, 0, 0.6); /* 半透明背景 */
  align-items: center;
  z-index: 1; /* 确保遮罩层在最上层 */
}
.custom-textarea {
  padding-right: 16px;
  :deep(.arco-textarea-clear-btn) {
    /* 调整清除按钮的样式，例如位置、大小等 */
    --at-apply: absolute right-[16px] top-[50%] transform: translateY(-50%);
  }
  // 限制字数位置
  :deep(.arco-textarea-word-limit) {
    right: var(--textarea-word-limit-right);
  }
  :deep(.arco-textarea) {
    padding-bottom: 24px;
  }
}
.custom-standard-textarea {
  padding-right: 36px;
  // :deep(.arco-textarea-clear-btn) {
  //   /* 调整清除按钮的样式，例如位置、大小等 */
  //   --at-apply: absolute right-[50px] top-[50%] transform: translateY(-50%);
  // }
}
.arco-textarea-word-limit {
  :deep(.arco-btn-shape-square:hover) {
    background-color: transparent;
  }
}
.no-require{
  :deep(.arco-form-item-label-required-symbol){
    display: none;
  }
}
:deep(.arco-input-number-step){
  display: none !important;
}
.no-label{
  :deep(.arco-form-item-label-col){
    display: none
  }
}
.reach-form-1753659875462{
  :deep(.arco-select-view-single .arco-select-view-value){
    white-space: unset;
    overflow: unset;
  }
}
</style>
